package com.example.springssm.handler;

import com.example.springssm.common.R;
import com.example.springssm.exception.BusinessException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.ConstraintViolationException;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.NoHandlerFoundException;


@RestControllerAdvice // 标记为全局控制器异常处理器
@Order
public class GlobalExceptionHandler {
    // 判断是否为Knife4j请求
    private boolean isKnife4jRequest() {
        HttpServletRequest request = ((ServletRequestAttributes)
                RequestContextHolder.currentRequestAttributes()).getRequest();
        String uri = request.getRequestURI();
        return uri.contains("/doc.html") ||
                uri.contains("/v3/api-docs") ||
                uri.contains("/webjars");
    }



    // 处理数据校验异常 (JSR 303/Jakarta Validation)
    @ExceptionHandler({MethodArgumentNotValidException.class, BindException.class})
    public R handleValidationException(Exception ex) {
        String errorMessage = "请求参数不合法";
        // 这里可以更精细地提取 BindingResult 中的错误信息
        // 例如: ex.getBindingResult().getFieldError().getDefaultMessage()
        return R.error(400, errorMessage);
    }

    // 处理 ConstraintViolationException (如 @RequestParam/@PathVariable 校验失败)
    @ExceptionHandler(ConstraintViolationException.class)
    public R handleConstraintViolationException(ConstraintViolationException ex, HttpServletRequest request) {
        String errorMessage = ex.getConstraintViolations().iterator().next().getMessage();
        return R.error(400, errorMessage);
    }

    // 处理自定义业务异常 (需要先定义)
    @ExceptionHandler(BusinessException.class)
    public R handleBusinessException(BusinessException ex, HttpServletRequest request) {
        return R.error(ex.getCode(), ex.getMessage());
    }

    // 处理其他所有未捕获异常
    @ExceptionHandler(Exception.class)
    public R handleException(Exception ex, HttpServletRequest request) {
        if (isKnife4jRequest()) {
            return null; // 关键：放行Knife4j请求
        }
        ex.printStackTrace(); // 记录日志
        return R.error(500, "系统繁忙，请稍后再试");
    }
}